<template>
  <div>
    <div style="display: flex; padding: 2rem">
      <div style="display: flex; align-items: center">
        <a-image width="40" src="/logo.png" />
        <h3 style="margin-left: 10px">会议日历</h3>
      </div>
      <div style="display: flex; margin-left: auto">
        <div style="margin-right: 70px">
          <a-button type="primary" @click="newMeetingChange()"
            >
会议室预约
</a-button
          >
        </div>
      </div>
    </div>

    <div>
      <div style="padding: 20px">
        <div><h4>会议状态：</h4></div>
        <div style="margin-top: 10px; display: flex">
          <div>
            <a-tabs
              position="left"
              default-active-key=""
              :hide-content="true"
              @change="tabsChange"
            >
              <a-tab-pane key="" title="所有">
                <!-- <calendar :type="'1'" /> -->
              </a-tab-pane>
              <a-tab-pane key="3" title="已结束">
                <!-- <calendar :type="'2'" /> -->
              </a-tab-pane>
              <a-tab-pane key="0" title="未开始">
                <!-- <calendar :type="'4'" /> -->
              </a-tab-pane>
            </a-tabs>
          </div>

          <div style="width: 80vw">
            <calendar ref="calendarRef" :type="calendarTypeValue" />
          </div>
        </div>
      </div>
    </div>

    <a-modal
      v-model:visible="newMeetingModalVisible"
      title-align="start"
      width="850px"
      :modal-style="{ maxHeight: '80vh' }"
      :body-style="{ padding: '0', maxHeight: 'calc(80vh - 100px)', overflow: 'hidden' }"
      @ok="handleOk"
      @cancel="handleCancel"
    >
      <template #title> 新建会议 </template>
      <div class="tabs-container">
        <a-tabs
          v-model:active-key="newMeetingTabsKeyValue"
          default-active-key="1"
          class="fixed-tabs"
          @change="newMeetingTabsChange"
        >
          <a-tab-pane key="1" title="会议信息">
            <div class="tabs-content">
              <meetingMessage
                ref="meetingMessageRef"
                :type="meetingMessageValue"
                :initial-user-info="initialUserInfo"
                @get-value="getSonValue"
                @get-meeting-type="getMeetingTypeFc"
              />
            </div>
          </a-tab-pane>
          <a-tab-pane v-if="meetingType === 0" key="3">
            <template #title>会议服务</template>
            <div class="tabs-content">
              <meetingService
                :type="meetingMessageValue"
                @get-meeting-service-form-value="getMeetingServiceChange"
              />
            </div>
          </a-tab-pane>
          <a-tab-pane v-if="meetingType === 0" key="4">
            <template #title>会议签到</template>
            <div class="tabs-content">
              <meetingSignln
                :type="meetingMessageValue"
                @meeting-signin-fc="meetingSigninBackFc"
              />
            </div>
          </a-tab-pane>
          <a-tab-pane key="5">
            <template #title>会务模板</template>
            <div class="tabs-content">
              <meetingTemplate @template-uploaded="onTemplateUploaded" />
            </div>
          </a-tab-pane>
        </a-tabs>
      </div>
      <template #footer>
        <div>
          <a-button @click="handleCancel">取消</a-button>
          <a-button type="primary" :loading="isSubmitting" :disabled="!meetingMessageRef?.isFormValid || isSubmitting" @click="handleOk">确定</a-button>
        </div>
      </template>
    </a-modal>

    <a-modal
      v-model:visible="meetingRoomVisible"
      width="70vw"
      @cancel="meetingRoomhandleCancel"
    >
      <template #title> </template>
      <meetRoomState />
    </a-modal>
  </div>
</template>

<script setup>
import { Message } from '@arco-design/web-vue'
import { nextTick, ref } from 'vue'
import dayjs from 'dayjs'
import calendar from './component/calendar.vue'
import meetingMessage from '@/views/meet/meetCalendar/component/meetingMessage.vue'
import meetingService from '@/views/meet/meetCalendar/component/meetingService.vue'
import meetingSignln from '@/views/meet/meetCalendar/component/meetingSignIn.vue'
import meetingTemplate from '@/views/meet/meetCalendar/component/meetingTemplate.vue'
import meetRoomState from '@/views/meet/meetRoomState/index.vue'
import { meetScheduledmeet } from '@/apis/meet/component'
import { getCurrentUserInfo } from '@/apis/system/user'

const newMeetingModalVisible = ref(false) // 新建会议弹窗变量
const meetingMessageValue = ref(false) // 子组件事件变量

const newMeetingTabsKeyValue = ref()
const meetingType = ref(0) // 会议类型 0=线下会议 1=线上会议
const calendarTypeValue = ref() // 向日程组件传递当前要请求的数据值
const meetingRoomVisible = ref(false) // 会议室占用情况的弹窗
const isSubmitting = ref(false) // 添加提交状态控制
const formQuery = ref({
  meetingConfig: {
    userId: '', // 预定人userId
    subject: '', // 会议主题
    startTime: '', // 开始时间
    length: '', // 持续时间
    mediaTypes: '', // 媒体类型
    meetRoomId: [], // 会议室id，初始化为空数组
    meetType: '', // 会议类型 0 线下 1 线上
    signEndTime: '', // 会议签到结束时间
    enableSignOut: '0', // 是否启用会议签退，0关闭，1开启
    signInBeforeMinutes: '', //	会议开始前多少分钟可以签到
    signOutMinutesAfterSignIn: '', // 会议签到多少分钟后才能签退
    signOutAfterEndMinutes: '', // 会议结束多少分钟后不能签退
    backgroundImageURL: null, // 图片链接
    updateMethod: '', // 更新方式：restoreDefault（恢复默认图片），single（单个图片更新），空（不更新）
    inviteScreen: 0, // 新增字段，默认不邀请
    confConfigInfo: {
      isGuestFreePwd: null, // 来宾是否免密
      callInRestriction: null, // 允许加入的会议范围 0：无限制 1：企业内部用户
      guestPwd: '', // 来宾密码
      enableWaitingRoom: null // 是否开启等候室
    },
    cycleParams: {
      startDate: '', // 开始日期 2025-02-25
      endDate: '', // 结束日期
      cycle: '', // 循环类型 Day，Week，Month
      interval: null, // 间隔时间 Integer
      point: [] // 周期点（如每周的哪些天）
    },
    attendees: [
      {
        accountId: '', // 与会者userid
        appId: ''
      }
    ],
    templateUrl: '' // 新增模板url字段
  },
  serviceList: []
})

const initialUserInfo = ref(null) // 新增

// 添加子组件引用
const meetingMessageRef = ref()
const calendarRef = ref()

/**
 * 新建会议按钮事件
 */
const newMeetingChange = async () => {
  try {
    const res = await getCurrentUserInfo()
    if (res && res.success && res.data) {
      // 不是admin才自动回显
      if (res.data.userid !== 'admin') {
        initialUserInfo.value = {
          realname: res.data.realname,
          userid: res.data.userid,
          avatar: res.data.avatar
        }
      } else {
        initialUserInfo.value = null
      }
    } else {
      initialUserInfo.value = null
    }
  } catch (e) {
    initialUserInfo.value = null
  }
  // 触发新建会议弹窗
  newMeetingModalVisible.value = true
}

/***
 * 会议签到页面表单回调
 */
const meetingSigninBackFc = (value) => {
  // 始终接收updateMethod值，无论是否为空字符串
  formQuery.value.meetingConfig.updateMethod = value.updateMethod

  // 其他字段保持不变
  formQuery.value.meetingConfig.backgroundImageURL = value.backgroundImageURL
  formQuery.value.meetingConfig.enableSignOut = value.enableSignOut
  formQuery.value.meetingConfig.signInBeforeMinutes = value.signInBeforeMinutes
  formQuery.value.meetingConfig.signOutAfterEndMinutes = value.signOutAfterEndMinutes
  formQuery.value.meetingConfig.signOutMinutesAfterSignIn = value.signOutMinutesAfterSignIn
  // 设置会议签到结束时间，默认为15分钟
  formQuery.value.meetingConfig.signEndTime = value.signInBeforeMinutes || '15'
}
/**
 * 标签卡点击事件
 */
const tabsChange = (e) => {
  calendarTypeValue.value = e
}
/**
 * 获取两个日期之间所有日期
 * @param startStr 开始日期
 * @param endStr 结束日期
 */
const getDaysBetween = (startStr, endStr) => {
  // 解析日期字符串为本地时间的Date对象
  const parseDate = (dateStr) => {
    const [year, month, day] = dateStr.split('-').map(Number)
    return new Date(year, month - 1, day)
  }

  let startDate = parseDate(startStr)
  let endDate = parseDate(endStr)

  // 确保开始日期不晚于结束日期
  if (startDate > endDate) {
    [startDate, endDate] = [endDate, startDate]
  }

  const days = []
  const currentDate = new Date(startDate.getTime())

  // 遍历每一天
  while (currentDate <= endDate) {
    days.push(currentDate.getDate()) // 获取当月第几天
    currentDate.setDate(currentDate.getDate() + 1) // 自动处理跨月
  }

  return days
}
/**
 *
 * @param daysArray 选择的月份中包含日的数组
 * @param startStr 开始时间
 * @param endStr 结束时间
 */
const monthScope = (daysArray, startStr, endStr) => {
  // 获取日期范围内的所有日（数字数组）
  const dateDays = getDaysBetween(startStr, endStr)

  // 将字符数组转换为数字数组（兼容字符串和数字混合输入）
  const targetDays = daysArray.map(Number)

  // 检查所有目标日是否都存在于日期范围中
  return targetDays.every(
    (day) =>
      Number.isInteger(day) // 过滤非数字
      && day >= 1
      && day <= 31 // 日期有效性验证
      && dateDays.includes(day)
  )
}
/**
 * 接受会议信息回传的会议类型
 * @param value 会议信息回传的会议类型值
 */
const getMeetingTypeFc = (value) => {
  // 确保meetingType是数字类型
  meetingType.value = Number(value)
}
/**
 * 日期计算并转换范围内周几
 * @param startStr 开始日期
 * @param endStr 结束日期
 */
const getWeekDaysBetween = (startStr, endStr) => {
  // 解析日期字符串为本地时间的Date对象
  const parseDate = (dateStr) => {
    const [year, month, day] = dateStr.split('-').map(Number)
    return new Date(year, month - 1, day)
  }
  let startDate = parseDate(startStr)
  let endDate = parseDate(endStr)
  // 确保开始日期不晚于结束日期
  if (startDate > endDate) {
    [startDate, endDate] = [endDate, startDate]
  }
  const weekDaysSet = new Set()
  // 遍历每一天
  const currentDate = new Date(startDate.getTime())
  while (currentDate <= endDate) {
    const dayIndex = currentDate.getDay()
    // 直接使用getDay()返回值，周日为0
    weekDaysSet.add(dayIndex)
    currentDate.setDate(currentDate.getDate() + 1)
  }
  return Array.from(weekDaysSet)
}
/**
 * 根据周选择的数组判断是否在开始日期和结束日期内
 * @param daysArray 周选择的多选数组
 * @param startStr 开始时间
 * @param endStr 结束时间
 */
const datefiltrate = (daysArray, startStr, endStr) => {
  // 获取日期范围内的星期数字数组
  const weekDays = getWeekDaysBetween(startStr, endStr)
  // 将字符数组转换为数字数组（兼容字符串和数字混合输入）
  const targetDays = daysArray.map(Number)
  // 检查所有目标星期是否都存在于日期范围中
  return targetDays.every((day) => weekDays.includes(day))
}
/**
 * 重置所有表单内容
 */
const resetForm = () => {
  // 重置会议信息组件表单
  if (meetingMessageRef.value) {
    meetingMessageRef.value.resetForm()
  }

  // 重置formQuery对象
  formQuery.value = {
    meetingConfig: {
      userId: '', // 预定人userId
      subject: '', // 会议主题
      startTime: '', // 开始时间
      length: '', // 持续时间
      mediaTypes: '', // 媒体类型
      meetRoomId: [], // 会议室id，初始化为空数组
      meetType: '', // 会议类型 0 线下 1 线上
      signEndTime: '', // 会议签到结束时间
      enableSignOut: '0', // 是否启用会议签退，0关闭，1开启
      signInBeforeMinutes: '', //	会议开始前多少分钟可以签到
      signOutMinutesAfterSignIn: '', // 会议签到多少分钟后才能签退
      signOutAfterEndMinutes: '', // 会议结束多少分钟后不能签退
      backgroundImageURL: null, // 图片链接
      updateMethod: '', // 更新方式：restoreDefault（恢复默认图片），single（单个图片更新），空（不更新）
      inviteScreen: 0, // 新增字段，默认不邀请
      confConfigInfo: {
        isGuestFreePwd: null, // 来宾是否免密
        callInRestriction: null, // 允许加入的会议范围 0：无限制 1：企业内部用户
        guestPwd: '', // 来宾密码
        enableWaitingRoom: null // 是否开启等候室
      },
      cycleParams: {
        startDate: '', // 开始日期 2025-02-25
        endDate: '', // 结束日期
        cycle: '', // 循环类型 Day，Week，Month
        interval: null, // 间隔时间 Integer
        point: [] // 周期点（如每周的哪些天）
      },
      attendees: [],
      templateUrl: '' // 新增模板url字段
    },
    serviceList: []
  }

  // 重置会议类型
  meetingType.value = 0

  // 重置标签页
  newMeetingTabsKeyValue.value = '1'
}
/**
 * 新建会议弹窗确认事件
 */
const handleOk = async () => {
  if (isSubmitting.value) return // 防止重复提交

  // 触发各组件更新数据
  meetingMessageValue.value = !meetingMessageValue.value
  await nextTick() // 等待子组件emit并同步数据

  // 表单前端校验
  const config = formQuery.value.meetingConfig
  // 1. 会议主题必填
  if (!config.subject || !config.subject.trim()) {
    Message.error('请输入会议主题')
    return
  }
  // 2. 会议开始时间大于当前时间
  if (!config.startTime || !dayjs(config.startTime).isAfter(dayjs(), 'minute')) {
    Message.error('会议开始时间需大于当前时间')
    return
  }
  // 3. 预约人必填
  if (!config.userId) {
    Message.error('请选择预约人')
    return
  }
  // 4. 参会人必填
  if (!config.attendees || config.attendees.length === 0) {
    Message.error('请选择与会者')
    return
  }
  // 5. 线下会议必须选择会议室
  if (config.meetType === '0' && (!config.meetRoomId || config.meetRoomId.length === 0)) {
    Message.error('请选择会议室')
    return
  }

  // 新增会议服务校验
  for (const [index, item] of (formQuery.value.serviceList || []).entries()) {
    if (item.serviceIds && item.serviceIds.length > 0 && (!item.userIds || item.userIds.length === 0)) {
      Message.error(`第${index + 1}项会议服务负责人未填写`)
      return
    }
    if (item.userIds && item.userIds.length > 0 && (!item.serviceIds || item.serviceIds.length === 0)) {
      Message.error(`第${index + 1}项会议服务项目未填写`)
      return
    }
  }

  isSubmitting.value = true // 开始提交，显示加载状态

  try {
    // 对于周期会议，验证周期设置
    if (config.cycleParams && config.cycleParams.cycle) {
      // 判断周期会议的周和月选择是否在开始时间和结束时间内
      if (config.cycleParams.cycle === 'Week') {
        const isDateScope = datefiltrate(
          config.cycleParams.point,
          config.cycleParams.startDate,
          config.cycleParams.endDate
        )
        if (isDateScope === false) {
          Message.error('请选择符合日期范围的星期')
          return
        }
      }

      if (config.cycleParams.cycle === 'Month') {
        const isDateScope = monthScope(
          config.cycleParams.point,
          config.cycleParams.startDate,
          config.cycleParams.endDate
        )
        if (isDateScope === false) {
          Message.error('请选择符合日期范围的日期')
          return
        }
      }
    }

    // 直接调用API提交完整数据前，兼容云会议mediaTypes
    if (config.meetType === '1') {
      config.mediaTypes = 'HDVideo'
    } else if (!config.mediaTypes) {
      config.mediaTypes = 'HDVideo'
    }
    // 直接调用API提交完整数据
    const res = await meetScheduledmeet(formQuery.value)
    if (res.success) {
      Message.success('会议预约成功')

      // 关闭弹窗
      newMeetingModalVisible.value = false

      // 重置表单
      resetForm()

      // 刷新日历组件，不再刷新整个页面
      calendarRef.value?.refresh()
    } else {
      Message.error(res.msg || '会议预约失败，请重试！')
    }
  } catch (error) {
    console.error('提交会议失败:', error)
    Message.error(error.message || '预约会议失败，请重试！')
  } finally {
    isSubmitting.value = false // 无论成功失败，都重置提交状态
  }
}
// 关闭会议室占用情况弹窗
const meetingRoomhandleCancel = () => {
  meetingRoomVisible.value = false
}
/**
 * 新建会议弹窗取消事件
 */
const handleCancel = () => {
  newMeetingModalVisible.value = false
}
/**
 * 服务会议表单回调事件
 */
const getMeetingServiceChange = (value) => {
  // 深拷贝，确保响应式和数据隔离
  formQuery.value.serviceList = JSON.parse(JSON.stringify(value.value || []))
}
/**
 * 获取子组件的数据
 */
const getSonValue = (value) => {
  // 获取会议信息表单后赋值给提交对象
  formQuery.value.meetingConfig.subject = value.subject
  formQuery.value.meetingConfig.startTime = value.startTime
  formQuery.value.meetingConfig.length = value.length
  formQuery.value.meetingConfig.mediaTypes = value.mediaTypes
  // 会议室直接赋值
  formQuery.value.meetingConfig.meetRoomId = Array.isArray(value.meetRoomId) ? value.meetRoomId : []
  // 会议类型直接用表单传回的值
  formQuery.value.meetingConfig.meetType = value.meetType
  // 修正：将selectedUsers转换为attendees结构（userid字段）
  formQuery.value.meetingConfig.attendees = (value.selectedUsers || []).map((user) => ({
    userid: user.userid,
    appId: '9dbd6b334e744eada42b45b3bf6b8402'
  }))
  formQuery.value.meetingConfig.userId = value.treeUser
  formQuery.value.meetingConfig.cycleParams = value.cycleParams
  formQuery.value.meetingConfig.confConfigInfo = value.confConfigInfo
  // 新增：同步inviteScreen参数
  formQuery.value.meetingConfig.inviteScreen = value.inviteScreen
}
/**
 * 新建会议弹窗标签卡切换事件
 */
const newMeetingTabsChange = async (_value) => {
  meetingMessageValue.value = !meetingMessageValue.value
  // 等待子组件emit完成并更新meetingMessageFromData
  await nextTick()
  // 不再强制验证会议信息填写
}

const onTemplateUploaded = (url) => {
  formQuery.value.meetingConfig.templateUrl = url
}
</script>

<style scoped>
:deep(.arco-modal) {
  max-height: 80vh;
}

:deep(.arco-modal-content) {
  max-height: 80vh;
  display: flex;
  flex-direction: column;
}

:deep(.arco-modal-body) {
  flex: 1;
  overflow: auto;
  padding: 0;
}

.tabs-container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.fixed-tabs {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: #fff;
  border-bottom: 1px solid #e8e8e8;
}

.tabs-content {
  padding: 16px;
  overflow-y: auto;
  max-height: calc(80vh - 180px);
}

:deep(.arco-tabs-nav) {
  margin-bottom: 0;
}

:deep(.arco-tabs-content) {
  height: 100%;
  overflow: visible;
}
</style>
